<?php
class ModulePaymentVk extends ModulePayment
{

    const PAYMENT_STATUS_DECLINE    = 3;
    const PAYMENT_STATUS_REFUND     = 4;
    const PAYMENT_STATUS_CHARGEBACK = 5;
    const PAYMENT_STATUS_DISPUTE    = 6;

    /**
     * @var ModuleSnsVk
     */
    private $moduleSns;

    /**
     * @see ModulePayment::__construct()
     */
    public function __construct($userId, $platform)
    {
        parent::__construct($userId, $platform);
        $this->moduleSns = ModuleSnsFactory::init(null, ModuleSnsConst::PFVK);
    }

    /**
     * @see ModulePayment::completeOrder()
     *
     * @return string | array(
     *  int $userId,
     *  ModulePaymentOrderVo $order
     *  array $paymentSetting
     * )
     */
    public function completeOrder()
    {
        /**
         * 获取商品信息的POST参数
         * array(
         *  'app_id' => 游戏ID,
         *  'item' => 道具信息(JS传入),
         *  'lang' => 语言,
         *  'notification_type' => 操作乐行('get_item' 或 'get_item_test'),
         *  'order_id' => 订单id,
         *  'receiver_id' => 用户平台UID,
         *  'user_id' => 用户平台UID,
         *  'sig' => 签名,
         * )
         * ------------------------
         * 完成支付的请求POST参数
         * array(
         *  'app_id' => 游戏ID,
         *  'date' => 时间,
         *  'item' => 道具信息(JS传入),
         *  'item_id' => 道具id,
         *  'item_photo_url' => 道具图片地址,
         *  'item_price' => 道具价格,
         *  'item_title' => 道具描述,
         *  'notification_type' => 操作乐行('order_status_change' 或 'order_status_change_test'),
         *  'order_id' => 订单id,
         *  'receiver_id' => 用户平台UID,
         *  'status' => 状态(chargeable),
         *  'user_id' => 用户平台UID,
         *  'sig' => 签名,
         * )
         * ------------------------
         * 完成支付的返回结果
         * array(
         *      'viewer_id': 用户平台UID,
         *      'res' => 平台订单id
         *      )
         * )
         */
        $input = SzParam::getWholePost();

        if (SzUtility::checkArrayKey('res', $input)) {
            $userId = $this->moduleSns->portPlayerUserId($input['viewer_id']);
            $profile = SzPersister::get()->getVo($userId, ModuleProfileConst::ORM_NAME_PROFILE);
            if (is_null($profile)) {
                return 100;
            }

            // 判断服务器是否维护中
            $appConfig = SzConfig::get()->loadAppConfig('app');
            if ($appConfig['MAINTENANCE']) {
                return 100;
            }

            /**
             * @var ModulePaymentOrderVoList $orderList
             * @var ModulePaymentOrderVo $order
             */
            $orderList = SzPersister::get()->getVoList(null, ModulePaymentConst::ORM_NAME_PAYMENT_ORDER, $userId);
            $latestOrder = null;
            $orderArray = $orderList->getList();
            krsort($orderArray);
            foreach ($orderArray as $order) {
                if ($order->getPlatformToken() == $input['res']) {
                    $latestOrder = $order;
                    break;
                }

                // platformToken 可能未知原因未更新，取最后一个订单
                if ($latestOrder == null) {
                    $latestOrder = $order;
                }
            }

            return array($userId, $latestOrder, null, true);
        }

        // 组织参数
        $sig = null;
        $str = '';
        if (SzUtility::checkArrayKey('sig', $input)) {
            $sig = $input['sig'];
            unset($input['sig']);
            ksort($input);
            foreach ($input as $k => $v) {
                $str .= $k.'='.$v;
            }
        }

        // 签名验证
        $payTokenConfig = ModuleSnsFactory::init(null, ModuleSnsConst::PFVK)->loadSnsSetting('appSecret');
        if ($sig != md5($str.$payTokenConfig['value'])) {
            return 10;
        } else {
            $return = null;
            switch ($input['notification_type']) {
                case 'get_item':
                case 'get_item_test':
                    $return = $this->getPaymentInfo($input['item']);
                    break;
                case 'order_status_change':
                case 'order_status_change_test':
                    $return = $this->completeOrderRealtimeUpdate($input);
                    break;
            }
            return $return;
        }
    }

    /**
     * Get payment def info.
     *
     * @param int $paymentDefId
     * @return string $info
     */
    protected function getPaymentInfo($paymentDefId)
    {
        $paymentSettings = SzConfig::get()->loadAppConfig(ModulePaymentConst::CONFIG_PAYMENT, null, true);

        if (!SzUtility::checkArrayKey($paymentDefId, $paymentSettings)) {
            return 20;
        }

        return array(null, null, $paymentSettings[$paymentDefId], false);
    }

    /**
     * Complete the payment from facebook realtime update.
     *
     * @param string $input data from $_POST
     * <pre>
     * array(
     *  'app_id' => 游戏ID,
     *  'date' => 时间,
     *  'item' => 道具信息(JS传入),
     *  'item_id' => 道具id,
     *  'item_photo_url' => 道具图片地址,
     *  'item_price' => 道具价格,
     *  'item_title' => 道具描述,
     *  'notification_type' => 操作乐行('order_status_change' 或 'order_status_change_test'),
     *  'order_id' => 订单id,
     *  'receiver_id' => 用户平台UID,
     *  'status' => 状态(chargeable),
     *  'user_id' => 用户平台UID,
     *  'sig' => 签名,
     * )
     * </pre>
     * @return string | array(
     *      int $userId,
     *      ModulePaymentOrderVo $order
     *      array $paymentSetting
     * )
     */
    private function completeOrderRealtimeUpdate($input)
    {
        if ($input['status'] != 'chargeable') {
            return 100;
        }

        // 判断游戏角色是否创建
        $platformId = $input['user_id'];
        $userId = $this->moduleSns->portPlayerUserId($platformId);
        $profile = SzPersister::get()->getVo($userId, ModuleProfileConst::ORM_NAME_PROFILE);
        if (is_null($profile)) {
            return 100;
        }

        // 判断服务器是否维护中
        $appConfig = SzConfig::get()->loadAppConfig('app');
        if ($appConfig['MAINTENANCE']) {
            return 100;
        }

        /**
         * @var ModulePaymentOrderVoList $orderList
         * @var ModulePaymentOrderVo $order
         */
        $orderList = SzPersister::get()->getVoList(null, ModulePaymentConst::ORM_NAME_PAYMENT_ORDER, $userId);
        foreach ($orderList->getList() as $order) {
            if ($order->getPlatformToken() == $input['order_id']) {
                return 100;
            }
        }

        // 未充值过，全新订单创建
        $paymentSetting = SzConfig::get()->loadAppConfig(ModulePaymentConst::CONFIG_PAYMENT, $input['item'], true);
        $order = $this->createOrder($userId, $paymentSetting, $input['order_id'], array(), true);

        // 计算充值数量与付费价格
        $quantity = 1;
        $paymentPrice = $paymentSetting['price'] * $quantity;

        $order = $this->completeOrderAndSupplyResources($userId, $order, $paymentSetting, $quantity);
        $order->setPrice($paymentPrice);
        $orderList->updateElement($order->getOrderId(), $order);
        SzPersister::get()->setVoList($orderList);

        return array($userId, $order, $paymentSetting, false);
    }


    /**
     * @see ModulePayment::completeOrderReturnValue()
     */
    public function completeOrderReturnValue($result)
    {
        // 返回结构
        $return = null;
        if (is_array($result)) {
            list(, $order, $paymentSetting, $isAlreadyComplete) = $result;

            if ($isAlreadyComplete) {
                return $order;
            } else {
                if (!is_null($order)
                    && $order instanceof ModulePaymentOrderVo) {
                    $return['response'] = array(
                        'order_id' => $order->getPlatformToken(),
                        'app_order_id' => $order->getOrderId(),
                    );
                } else {
                    $appConfig = SzConfig::get()->loadAppConfig('app');
                    $return['response'] = array(
                        'item_id' => $paymentSetting['paymentDefId'],
                        'title' => $paymentSetting['name'],
                        'photo_url' => 'https://' . $appConfig['CDN_HOST'] . '/apps/master/' . $appConfig['PHP_VER'] . '/www' . '/img/' . $appConfig['LANG'] . '/payment/' . $paymentSetting['icon'],
                        'price' => $paymentSetting['price'] * $paymentSetting['exchangeRate'][ModuleSnsConst::PFVK]
                    );
                }
                return json_encode($return);
            }

        } else {
            $return['error'] = array(
                'error_code' => $result,
                'error_msg' => 'payment error',
                'critical' => true
            );
            return json_encode($return);
        }
    }

    /**
     * @see ModulePayment::repairOrder()
     */
    public function repairOrder($userId, $orderInfo)
    {
    }
}